package astra.client.utils.widgets.table;

import astra.client.models.TableRequestResult;
import astra.client.services.Filter;
import astra.client.services.HasId;
import astra.client.services.DataSource;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.ColumnSortEvent;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.view.client.AsyncDataProvider;
import com.google.gwt.view.client.HasData;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Kotelnikov Dmitry <a href="mailto:dimonnot@mail.ru"/>
 */
public class AdvancedTable<T extends HasId> extends FlowPanel{
    private CellTable<T> table;
    private AsyncDataProvider<T> dataProvider;
    private SimplePager pager;
    private DataSource dataSource;
    private int rowsPerPage = 20;
    private boolean requestSize = true;

    public AdvancedTable(List<TableColumn<T>> columns, DataSource dataSource) {
        this.dataSource = dataSource;

        table = new CellTable<T>();
        table.setWidth("100%");
        for (TableColumn<T> column: columns) {
            table.addColumn(column.column, column.name);
        }

        pager = new SimplePager();
        pager.setDisplay(table);

        dataProvider = new AsyncDataProvider<T>() {
            @Override
            protected void onRangeChanged(final HasData<T> display) {
                refreshData();
            }
        };
        dataProvider.addDataDisplay(table);

        ColumnSortEvent.AsyncHandler columnSortHandler = new ColumnSortEvent.AsyncHandler(table);
        table.addColumnSortHandler(columnSortHandler);

        table.setRowCount(rowsPerPage);
        table.setLoadingIndicator(new Label("Идет загрузка данных"));

        setWidth("100%");

        add(table);
        add(pager);
    }

    public void setData(TableRequestResult<HasId> result) {
        dataProvider.updateRowCount(result.getCount(), true);
        List<T> rows = new ArrayList<T>();
        for (HasId object:result.getRows()) {
            rows.add((T)object);
        }
        dataProvider.updateRowData(0,rows);
        requestSize = false;
    }

    public void refresh() {
        requestSize = true;
        refreshData();
    }

    protected void refreshData() {
        int page = pager.getPage() + 1;
        dataSource.get((page > 0 ? page : 1), pager.getPageSize(), requestSize,
            new AsyncCallback<TableRequestResult<HasId>>(){
                @Override
                public void onFailure(Throwable caught) {
                    Window.alert("Не удается загрузить данные");
                }

                @Override
                public void onSuccess(TableRequestResult<HasId> result) {
                    setData(result);
                }
            }
        );
    }
}
